<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>服务器信息</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script type="text/javascript" src="js/plugin/jquery.min.js"></script>
    <script type="text/javascript" src="js/plugin/vue/vue-2.4.2.min.js"></script>
    <style>
html,body{font-size:12px;margin:0;padding:0;height:100%;color:#999;overflow-x:hidden;}
.hide{display:none;}
.key{color:#36F;}
.value1{color:#F36;}
.value{}
.value{}
.p_system .type_system{color:#F63}
.p_const .type_const{color:#F63}
.p_eq_ref .type_eq_ref{color:#F63}
.p_ref .type_ref{color:#F63}
.p_range .type_range{color:#F63}
.p_index .type_index{color:#F63}
.p_ALL  .type_ALL {color:#F63}
.hide_ext .can_hide{display:none}
.hide{display:none}
    </style>
</head>
<body>
<textarea id="explain" name="explain" style="width: calc(100% - 200px)"> </textarea>
<button onclick="explain()">提交</button>
<button id="showExt" class=" hide" onclick="showExt()">展开</button>
<button id="hideExt" class="" onclick="hideExt()">收起</button>
<div id="body" :title="r">

    <!-- 应用信息 -->
    <div id="head_line">
        <span class="key">select_id</span> : <span class="value">{{explain.query_block.select_id}}</span><br/>
        <span v-for="(value, key) in explain.query_block.cost_info">
            <span class="key">执行成本 {{key}}</span> : <span class="value"> {{value}}</span><br/>
        </span>
    </div>
    <br/>
    <!-- jvm信息 -->
    <div id="nested_loop" v-if="'nested_loop' in explain.query_block" :set="x = explain.query_block.nested_loop">
        <div v-for="(line, idx) in x">
            <span class="line"><span class="key">表名 table</span> : <span class="value1">{{line.table.table_name}}</span><br/></span>
            <span class="line"><span class="key">查询类型 access_type</span> : <span :class="['value2 p_'+line.table.access_type]"><span class="type_system">system</span>><span class="type_const">const</span>><span class="type_eq_ref">eq_ref</span>><span class="type_ref">ref</span>><span class="type_range">range</span>><span class="type_index">index</span>><span class="type_ALL">ALL</span></span><br/></span>
            <span class="line can_hide"><span class="key">可用索引 possible_keys</span> : <span class="value">{{line.table.possible_keys}}</span><br/></span>
            <span class="line"><span class="key">实际索引 key</span> : <span class="value1">{{line.table.key}}</span><br/></span>
            <span class="line can_hide"><span class="key"> used_key_parts</span> : <span class="value">{{line.table.used_key_parts}}</span><br/></span>
            <span class="line can_hide"><span class="key">索引长度 key_length</span> : <span class="value">{{line.table.key_length}}</span><br/></span>
            <span class="line can_hide"><span class="key">大致行数 rows_examined_per_scan</span> : <span class="value">{{line.table.rows_examined_per_scan}}</span><br/></span>
            <span class="line can_hide"><span class="key">扇区数 rows_produced_per_join</span> : <span class="value">{{line.table.rows_produced_per_join}}</span><br/></span>
            <span class="line can_hide"><span class="key">索引区分度 filtered</span> : <span class="value">{{line.table.filtered}}</span><br/></span>
            <span class="line"><span class="key">索引条件 index_condition</span> : <span class="value1">{{line.table.index_condition}}</span><br/></span>
            <span class="line can_hide"><span class="key">读盘成本 cost_info.read_cost</span> : <span class="value">{{line.table.cost_info.read_cost}}</span><br/></span>
            <span class="line can_hide"><span class="key">执行成本(join) cost_info.eval_cost</span> : <span class="value">{{line.table.cost_info.eval_cost}}</span><br/></span>
            <span class="line can_hide"><span class="key">前置成本(上面两个求和) cost_info.prefix_cost</span> : <span class="value">{{line.table.cost_info.prefix_cost}}</span><br/></span>
            <span class="line can_hide"><span class="key">连接行数(rows_examined_per_scan*filtered) cost_info.data_read_per_join</span> : <span class="value">{{line.table.cost_info.data_read_per_join}}</span><br/></span>
            <span class="line"><span class="key">查到的列 used_columns</span> : <span class="value1">{{line.table.used_columns}}</span><br/></span>
            <span class="line"><span class="key">单表条件 attached_condition</span> : <span class="value">{{line.table.attached_condition}}</span><br/></span>
            <br/>
        </div>
    </div>
    <div id="ordering_operation" v-if="'ordering_operation' in explain.query_block"  :set="x = explain.query_block.ordering_operation">
        <span class="key">是否磁盘排序 using_filesort</span> : <span class="value">{{x.using_filesort}}</span><br/>
        <br/>
        <div v-for="(line, idx) in x.nested_loop">
            <span class="line"><span class="key">表名 table</span> : <span class="value1">{{line.table.table_name}}</span><br/></span>
            <span class="line"><span class="key">查询类型 access_type</span> : <span :class="['value2 p_'+line.table.access_type]"><span class="type_system">system</span>><span class="type_const">const</span>><span class="type_eq_ref">eq_ref</span>><span class="type_ref">ref</span>><span class="type_range">range</span>><span class="type_index">index</span>><span class="type_ALL">ALL</span></span><br/></span>
            <span class="line can_hide"><span class="key">可用索引 possible_keys</span> : <span class="value">{{line.table.possible_keys}}</span><br/></span>
            <span class="line"><span class="key">实际索引 key</span> : <span class="value1">{{line.table.key}}</span><br/></span>
            <span class="line can_hide"><span class="key"> used_key_parts</span> : <span class="value">{{line.table.used_key_parts}}</span><br/></span>
            <span class="line can_hide"><span class="key">索引长度 key_length</span> : <span class="value">{{line.table.key_length}}</span><br/></span>
            <span class="line can_hide"><span class="key">大致行数 rows_examined_per_scan</span> : <span class="value">{{line.table.rows_examined_per_scan}}</span><br/></span>
            <span class="line can_hide"><span class="key">扇区数 rows_produced_per_join</span> : <span class="value">{{line.table.rows_produced_per_join}}</span><br/></span>
            <span class="line can_hide"><span class="key">索引区分度 filtered</span> : <span class="value">{{line.table.filtered}}</span><br/></span>
            <span class="line"><span class="key">索引条件 index_condition</span> : <span class="value1">{{line.table.index_condition}}</span><br/></span>
            <span class="line can_hide"><span class="key">读盘成本 cost_info.read_cost</span> : <span class="value">{{line.table.cost_info.read_cost}}</span><br/></span>
            <span class="line can_hide"><span class="key">执行成本(join) cost_info.eval_cost</span> : <span class="value">{{line.table.cost_info.eval_cost}}</span><br/></span>
            <span class="line can_hide"><span class="key">前置成本(上面两个求和) cost_info.prefix_cost</span> : <span class="value">{{line.table.cost_info.prefix_cost}}</span><br/></span>
            <span class="line can_hide"><span class="key">连接行数(rows_examined_per_scan*filtered) cost_info.data_read_per_join</span> : <span class="value">{{line.table.cost_info.data_read_per_join}}</span><br/></span>
            <span class="line"><span class="key">查到的列 used_columns</span> : <span class="value1">{{line.table.used_columns}}</span><br/></span>
            <span class="line"><span class="key">单表条件 attached_condition</span> : <span class="value">{{line.table.attached_condition}}</span><br/></span>
            <br/>
        </div>
    </div>
</div>

<script type="text/javascript">
    var init_ajax = 0;
    var sybn = new Vue({
      el: '#body',
//      components:{
//        'my-nested_loop': {
//            template: '#my-nested_loop_template',
//            data() {
//                return {
//                    myMsg:111
//                }
//            }
//        }
//      },
      data: {
        explain: {
          "query_block": {
            "select_id": 1,
            "cost_info": {
              "query_cost": "55.81"
            },
            "ordering_operation": {
              "using_filesort": false,
              "nested_loop": [
                {
                  "table": {
                    "table_name": "rmt",
                    "access_type": "range",
                    "possible_keys": [
                      "I_MT_SALE_TIME",
                      "I_MT_SHOW_TIME"
                    ],
                    "key": "I_MT_SHOW_TIME",
                    "used_key_parts": [
                      "SHOW_TIME"
                    ],
                    "key_length": "63",
                    "rows_examined_per_scan": 28,
                    "rows_produced_per_join": 0,
                    "filtered": "0.18",
                    "index_condition": "((`cms`.`rmt`.`SHOW_TIME` >= <cache>(convert(date_format('2023-03-15 06:00','%Y-%m-%dT%H:%i:%s') using utf8))) and (`cms`.`rmt`.`SHOW_TIME` < <cache>(convert(date_format('2023-03-16 06:00','%Y-%m-%dT%H:%i:%s') using utf8))))",
                    "cost_info": {
                      "read_cost": "40.20",
                      "eval_cost": "0.01",
                      "prefix_cost": "40.21",
                      "data_read_per_join": "267"
                    },
                    "used_columns": [
                      "ID",
                      "UID",
                      "UID_CINEMA",
                      "UID_SALE_GOODS",
                      "UID_PLAN_TIME",
                      "SALE_BILL_CODE",
                      "TRANSACTION_CODE",
                      "CINEMA_TICKET_CODE",
                      "MOVIE_NAME",
                      "HALL_NAME",
                      "MOVIE_LANGUAGE",
                      "SEAT_ROW_NO",
                      "SEAT_COLUMN_NO",
                      "TICKET_TYPE_NAME",
                      "TICKET_PRICE",
                      "SERVICE_FEE",
                      "SHOW_TIME",
                      "SALE_TIME",
                      "SALE_USER_NAME",
                      "SALE_TYPE",
                      "CHANNEL_NAME",
                      "SALE_CHANNEL_NAME",
                      "MEMBER_NAME",
                      "MEMBER_CLASS_NAME",
                      "GD_BILL_CODE",
                      "GET_STATUS",
                      "GET_TIME",
                      "APPLY_STATUS",
                      "COUPON_INFO"
                    ],
                    "attached_condition": "((`cms`.`rmt`.`UID_CINEMA` = 'c398deee-972a-48d0-9a5c-50a4c46ffba1') and (`cms`.`rmt`.`APPLY_STATUS` in (1,3)) and (`cms`.`rmt`.`SALE_TIME` >= '2023-03-15 06:00') and (`cms`.`rmt`.`SALE_TIME` < '2023-03-16 06:00'))"
                  }
                },
                {
                  "table": {
                    "table_name": "pt",
                    "access_type": "eq_ref",
                    "possible_keys": [
                      "UQ_SCH_PLAN_TIME_UID"
                    ],
                    "key": "UQ_SCH_PLAN_TIME_UID",
                    "used_key_parts": [
                      "UID"
                    ],
                    "key_length": "108",
                    "ref": [
                      "cms.rmt.UID_PLAN_TIME"
                    ],
                    "rows_examined_per_scan": 1,
                    "rows_produced_per_join": 0,
                    "filtered": "100.00",
                    "cost_info": {
                      "read_cost": "0.05",
                      "eval_cost": "0.01",
                      "prefix_cost": "40.27",
                      "data_read_per_join": "72"
                    },
                    "used_columns": [
                      "TIME_ID",
                      "UID",
                      "SHOW_INDEX",
                      "MIN_PRICE"
                    ],
                    "attached_condition": "<if>(is_not_null_compl(pt), (`cms`.`pt`.`UID` = `cms`.`rmt`.`UID_PLAN_TIME`), true)"
                  }
                },
                {
                  "table": {
                    "table_name": "rso",
                    "access_type": "ref",
                    "possible_keys": [
                      "I_RSO_RELATION_GOODS_UID_TYPE"
                    ],
                    "key": "I_RSO_RELATION_GOODS_UID_TYPE",
                    "used_key_parts": [
                      "RELATION_GOODS_UID"
                    ],
                    "key_length": "111",
                    "ref": [
                      "cms.rmt.UID_SALE_GOODS"
                    ],
                    "rows_examined_per_scan": 1059,
                    "rows_produced_per_join": 52,
                    "filtered": "100.00",
                    "cost_info": {
                      "read_cost": "4.95",
                      "eval_cost": "10.59",
                      "prefix_cost": "55.81",
                      "data_read_per_join": "150K"
                    },
                    "used_columns": [
                      "ID",
                      "RELATION_GOODS_UID",
                      "SALE_TYPE",
                      "PAY_PRICE"
                    ],
                    "attached_condition": "<if>(is_not_null_compl(rso), ((`cms`.`rso`.`SALE_TYPE` = `cms`.`rmt`.`SALE_TYPE`) or (`cms`.`rmt`.`SALE_TYPE` = '3')), true)"
                  }
                }
              ]
            }
          }
        },
        r: getQueryString("r"),
        crawlerName: getQueryString("crawlerName"),
        crawlerName2: "服务器状态接口调用中..."
      },
      methods: {
        getCurrentTime: function() {
            //获取当前时间并打印
            var _this = this;
            let yy = new Date().getFullYear();
            let mm = new Date().getMonth()+1;
            let dd = new Date().getDate();
            let hh = new Date().getHours();
            let mf = new Date().getMinutes()<10 ? '0'+new Date().getMinutes() : new Date().getMinutes();
            let ss = new Date().getSeconds()<10 ? '0'+new Date().getSeconds() : new Date().getSeconds();
            _this.gettime = mm+'-'+dd+' '+hh+':'+mf+':'+ss;
            return _this.gettime;
        },
      },
      computed: {
      }
    });

    function getQueryString(name, defaults) {
      var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
      var r = window.location.search.substr(1).match(reg);
      if (r != null) return decodeURIComponent(r[2]); return defaults || null;
    }
    function omitLog(log, length) {
      var res = "" + log;
      length = length || 32;
      if (res.length > length && length > 3) {
        res = res.substr(0, length-3) + "...";
      }
      return res;
    }
    function explain() {
      var explain = document.getElementById('explain').value;
      explain = explain.trim();
      if (explain) {
        try {
            sybn.explain = eval("("+explain+")");
        } catch (e) {
            console.log("发生异常:" + e)
        }
      }
    }

    function showExt() {
        document.getElementById('body').classList.remove("hide_ext");
        document.getElementById('showExt').classList.add("hide");
        document.getElementById('hideExt').classList.remove("hide");
    }
    function hideExt() {
        document.getElementById('body').classList.add("hide_ext");
        document.getElementById('showExt').classList.remove("hide");
        document.getElementById('hideExt').classList.add("hide");
    }
  </script>
</body>
</html>